package org.example.jwtcheck;


import cn.hutool.json.JSONUtil;
import org.example.common.GlobalConts;
import org.example.common.R;
import org.example.utils.JwtUtils;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import reactor.core.publisher.Mono;

/**
 * 类名必须以GatewayFilterFactory结尾,yml中的filter匹配的则是GatewayFilterFactory前面的部分
 */
public class JwtCheckGatewayFilterFactory extends AbstractGatewayFilterFactory<JwtCheckGatewayFilterFactory.Config> {

    public JwtCheckGatewayFilterFactory() {
        super(Config.class);
    }

    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {
            ServerHttpRequest request = exchange.getRequest();
            // 从请求header获取token
            String jwtToken = request.getHeaders().getFirst("token");
            if(jwtToken==null){
                // 从请求参数中获取token
                jwtToken = request.getQueryParams().getFirst("token");
            }
            //校验jwtToken的合法性
            if (JwtUtils.validToken(jwtToken)) {
                ServerHttpRequest.Builder builder = request.mutate();
                // 把当前登录成功的用户id放入header
                builder.header(GlobalConts.LOGIN_SUCCESS_USER_HEADER_KEY, JwtUtils.parseToken(jwtToken)+"");
                return chain.filter(exchange.mutate().request(builder.build()).build());
            }
            //token验证失败,响应未登录的异常
            ServerHttpResponse response = exchange.getResponse();
            //设置headers
            HttpHeaders httpHeaders = response.getHeaders();
            httpHeaders.add("Content-Type", "application/json; charset=UTF-8");
            httpHeaders.add("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0");
            //设置body
            R result = new R();
            result.setCode(401);
            result.setMsg("认证失败");
            result.setData(null);
            String errJson = JSONUtil.toJsonStr(result);
            DataBuffer bodyDataBuffer = response.bufferFactory().wrap(errJson.getBytes());
            return response.writeWith(Mono.just(bodyDataBuffer));
        };
    }

    public static class Config {
        //Put the configuration properties for your filter here
    }
}